Source for file class.ezpdf.php
Documentation is available at class.ezpdf.php
include_once('includes/class.pdf.php');
//==============================================================================
// this class will take the basic interaction facilities of the Cpdf class
// and make more useful functions so that the user does not have to
// know all the ins and outs of pdf presentation to produce something pretty.
// there is no warranty, implied or otherwise with this software.
// version 009 (versioning is linked to class.pdf.php)
// released under a public domain licence.
// Wayne Munro, R&OS Ltd, http://www.ros.co.nz/pdf
//==============================================================================
var $ez=
array('fontSize'=>
10); // used for storing most of the page configuration parameters
var $y; // this is the current vertical positon on the page of the writing point, very important
var $ezPages=
array(); // keep an array of the ids of the pages, making it easy to go back and add page numbers etc.
// ------------------------------------------------------------------------------
function Cezpdf($paper=
'a4',$orientation=
'portrait'){
// Assuming that people don't want to specify the paper size using the absolute coordinates
// allow a couple of options:
// orientation can be 'portrait' or 'landscape'
// or, to actually set the coordinates, then pass an array in as the first parameter.
// the defaults are as shown.
// -------------------------
// 2002-07-24 - Nicola Asuni (info@tecnick.com):
// Added new page formats (45 standard ISO paper formats and 4 american common formats)
// paper cordinates are calculated in this way: (inches * 72) where 1 inch = 2.54 cm
// Now you may also pass a 2 values array containing the page width and height in centimeters
// -------------------------
case '4A0':
{$size =
array(0,0,4767.87,6740.79); break;}
case '2A0':
{$size =
array(0,0,3370.39,4767.87); break;}
case 'A0':
{$size =
array(0,0,2383.94,3370.39); break;}
case 'A1':
{$size =
array(0,0,1683.78,2383.94); break;}
case 'A2':
{$size =
array(0,0,1190.55,1683.78); break;}
case 'A3':
{$size =
array(0,0,841.89,1190.55); break;}
case 'A4':
default:
{$size =
array(0,0,595.28,841.89); break;}
case 'A5':
{$size =
array(0,0,419.53,595.28); break;}
case 'A6':
{$size =
array(0,0,297.64,419.53); break;}
case 'A7':
{$size =
array(0,0,209.76,297.64); break;}
case 'A8':
{$size =
array(0,0,147.40,209.76); break;}
case 'A9':
{$size =
array(0,0,104.88,147.40); break;}
case 'A10':
{$size =
array(0,0,73.70,104.88); break;}
case 'B0':
{$size =
array(0,0,2834.65,4008.19); break;}
case 'B1':
{$size =
array(0,0,2004.09,2834.65); break;}
case 'B2':
{$size =
array(0,0,1417.32,2004.09); break;}
case 'B3':
{$size =
array(0,0,1000.63,1417.32); break;}
case 'B4':
{$size =
array(0,0,708.66,1000.63); break;}
case 'B5':
{$size =
array(0,0,498.90,708.66); break;}
case 'B6':
{$size =
array(0,0,354.33,498.90); break;}
case 'B7':
{$size =
array(0,0,249.45,354.33); break;}
case 'B8':
{$size =
array(0,0,175.75,249.45); break;}
case 'B9':
{$size =
array(0,0,124.72,175.75); break;}
case 'B10':
{$size =
array(0,0,87.87,124.72); break;}
case 'C0':
{$size =
array(0,0,2599.37,3676.54); break;}
case 'C1':
{$size =
array(0,0,1836.85,2599.37); break;}
case 'C2':
{$size =
array(0,0,1298.27,1836.85); break;}
case 'C3':
{$size =
array(0,0,918.43,1298.27); break;}
case 'C4':
{$size =
array(0,0,649.13,918.43); break;}
case 'C5':
{$size =
array(0,0,459.21,649.13); break;}
case 'C6':
{$size =
array(0,0,323.15,459.21); break;}
case 'C7':
{$size =
array(0,0,229.61,323.15); break;}
case 'C8':
{$size =
array(0,0,161.57,229.61); break;}
case 'C9':
{$size =
array(0,0,113.39,161.57); break;}
case 'C10':
{$size =
array(0,0,79.37,113.39); break;}
case 'RA0':
{$size =
array(0,0,2437.80,3458.27); break;}
case 'RA1':
{$size =
array(0,0,1729.13,2437.80); break;}
case 'RA2':
{$size =
array(0,0,1218.90,1729.13); break;}
case 'RA3':
{$size =
array(0,0,864.57,1218.90); break;}
case 'RA4':
{$size =
array(0,0,609.45,864.57); break;}
case 'SRA0':
{$size =
array(0,0,2551.18,3628.35); break;}
case 'SRA1':
{$size =
array(0,0,1814.17,2551.18); break;}
case 'SRA2':
{$size =
array(0,0,1275.59,1814.17); break;}
case 'SRA3':
{$size =
array(0,0,907.09,1275.59); break;}
case 'SRA4':
{$size =
array(0,0,637.80,907.09); break;}
case 'LETTER':
{$size =
array(0,0,612.00,792.00); break;}
case 'LEGAL':
{$size =
array(0,0,612.00,1008.00); break;}
case 'EXECUTIVE':
{$size =
array(0,0,521.86,756.00); break;}
case 'FOLIO':
{$size =
array(0,0,612.00,936.00); break;}
// then an array was sent it to set the size
else { //size in centimeters has been passed
$size[2] =
( $paper[0] /
2.54 ) *
72;
$size[3] =
( $paper[1] /
2.54 ) *
72;
$this->ez['pageWidth']=
$size[2];
$this->ez['pageHeight']=
$size[3];
// also set the margins to some reasonable defaults
$this->ez['topMargin']=
30;
$this->ez['bottomMargin']=
30;
$this->ez['leftMargin']=
30;
$this->ez['rightMargin']=
30;
// set the current writing position to the top of the first page
$this->y =
$this->ez['pageHeight']-
$this->ez['topMargin'];
// and get the ID of the page that was created during the instancing process.
$this->ezPages[1]=
$this->getFirstPageId();
// ------------------------------------------------------------------------------
// 2002-07-24: Nicola Asuni (info@tecnick.com)
// Set Margins in centimeters
$top =
( $top /
2.54 ) *
72;
$bottom =
( $bottom /
2.54 ) *
72;
$left =
( $left /
2.54 ) *
72;
$right =
( $right /
2.54 ) *
72;
// ------------------------------------------------------------------------------
// start from the current y-position, make the set number of columne
if (isset
($this->ez['columns']) &&
$this->ez['columns']==
1){
// if we are already in a column mode then just return.
$def=
array('gap'=>
10,'num'=>
2);
if (!isset
($options[$k])){
$this->ez['columns']=
array('on'=>
1,'colNum'=>
1);
// store the current margins
$this->ez['columns']['margins']=
array(
,$this->ez['rightMargin']
,$this->ez['bottomMargin']
// and store the settings for the columns
$this->ez['columns']['options']=
$options;
// then reset the margins to suit the new columns
// safe enough to assume the first column here, but start from the current y-position
$this->ez['topMargin']=
$this->ez['pageHeight']-
$this->y;
$width=
($this->ez['pageWidth']-
$this->ez['leftMargin']-
$this->ez['rightMargin']-
($options['num']-
1)*
$options['gap'])/
$options['num'];
$this->ez['columns']['width']=
$width;
$this->ez['rightMargin']=
$this->ez['pageWidth']-
$this->ez['leftMargin']-
$width;
// ------------------------------------------------------------------------------
if (isset
($this->ez['columns']) &&
$this->ez['columns']['on']==
1){
$this->ez['columns']['on']=
0;
$this->ez['leftMargin']=
$this->ez['columns']['margins'][0];
$this->ez['rightMargin']=
$this->ez['columns']['margins'][1];
$this->ez['topMargin']=
$this->ez['columns']['margins'][2];
$this->ez['bottomMargin']=
$this->ez['columns']['margins'][3];
// ------------------------------------------------------------------------------
// puts the document into insert mode. new pages are inserted until this is re-called with status=0
// by default pages wil be inserted at the start of the document
if (isset
($this->ezPages[$pageNum])){
$this->ez['insertMode']=
1;
$this->ez['insertOptions']=
array('id'=>
$this->ezPages[$pageNum],'pos'=>
$pos);
$this->ez['insertMode']=
0;
// ------------------------------------------------------------------------------
if (isset
($this->ez['columns']) &&
$this->ez['columns']['on']==
1){
// check if this is just going to a new column
// increment the column number
$this->ez['columns']['colNum']++
;
//echo $this->ez['columns']['colNum'].'<br>';
if ($this->ez['columns']['colNum'] <=
$this->ez['columns']['options']['num']){
// then just reset to the top of the next column
$this->ez['columns']['colNum']=
1;
$this->ez['topMargin']=
$this->ez['columns']['margins'][2];
$width =
$this->ez['columns']['width'];
$this->ez['leftMargin']=
$this->ez['columns']['margins'][0]+
($this->ez['columns']['colNum']-
1)*
($this->ez['columns']['options']['gap']+
$width);
$this->ez['rightMargin']=
$this->ez['pageWidth']-
$this->ez['leftMargin']-
$width;
//echo 'left='.$this->ez['leftMargin'].' right='.$this->ez['rightMargin'].'<br>';
// make a new page, setting the writing point back to the top
$this->y =
$this->ez['pageHeight']-
$this->ez['topMargin'];
// make the new page with a call to the basic class.
if (isset
($this->ez['insertMode']) &&
$this->ez['insertMode']==
1){
$id =
$this->ezPages[$this->ezPageCount] =
$this->newPage(1,$this->ez['insertOptions']['id'],$this->ez['insertOptions']['pos']);
// then manipulate the insert options so that inserted pages follow each other
$this->ez['insertOptions']['id']=
$id;
$this->ez['insertOptions']['pos']=
'after';
$this->y =
$this->ez['pageHeight']-
$this->ez['topMargin'];
// ------------------------------------------------------------------------------
// sets the margins to new values
$this->ez['topMargin']=
$top;
$this->ez['bottomMargin']=
$bottom;
$this->ez['leftMargin']=
$left;
$this->ez['rightMargin']=
$right;
// check to see if this means that the current writing position is outside the
if ($this->y >
$this->ez['pageHeight']-
$top){
$this->y =
$this->ez['pageHeight']-
$top;
if ( $this->y <
$bottom){
// ------------------------------------------------------------------------------
// return the strict numbering (1,2,3,4..) number of the current page
// ------------------------------------------------------------------------------
function ezStartPageNumbers($x,$y,$size,$pos=
'left',$pattern=
'{PAGENUM} of {TOTALPAGENUM}',$num=
''){
// put page numbers on the pages from here.
// place then on the 'pos' side of the coordinates (x,y).
// pos can be 'left' or 'right'
// use the given 'pattern' for display, where (PAGENUM} and {TOTALPAGENUM} are replaced
// if $num is set, then make the first page this number, the number of total pages will
// be adjusted to account for this.
// Adjust this function so that each time you 'start' page numbers then you effectively start a different batch
// return the number of the batch, so that they can be stopped in a different order if required.
if (!$pattern ||
!strlen($pattern)){
$pattern=
'{PAGENUM} of {TOTALPAGENUM}';
if (!isset
($this->ez['pageNumbering'])){
$this->ez['pageNumbering']=
array();
$i =
count($this->ez['pageNumbering']);
$this->ez['pageNumbering'][$i][$this->ezPageCount]=
array('x'=>
$x,'y'=>
$y,'pos'=>
$pos,'pattern'=>
$pattern,'num'=>
$num,'size'=>
$size);
// ------------------------------------------------------------------------------
// given a particular generic page number (ie, document numbered sequentially from beginning),
// return the page number under a particular page numbering scheme ($i)
if (!isset
($this->ez['pageNumbering']))
$this->addMessage('WARNING: page numbering called for and wasn\'t started with ezStartPageNumbers');
foreach($this->ez['pageNumbering'][$i] as $k=>
$v){
$num=
$pageNum-
$startNum+
$start;
// ------------------------------------------------------------------------------
// if stopTotal=1 then the totalling of pages for this number will stop too
// if $next=1, then do this page, but not the next, else do not do this page either
// if $i is set, then stop that particular pagenumbering sequence.
if (!isset
($this->ez['pageNumbering'])){
$this->ez['pageNumbering']=
array();
// then this has only just been started, this will over-write the start, and nothing will appear
// add a special command to the start block, telling it to stop as well
// ------------------------------------------------------------------------------
// ------------------------------------------------------------------------------
// this will go through the pageNumbering array and add the page numbers are required
if (isset
($this->ez['pageNumbering'])){
$tmp1=
$this->ez['pageNumbering'];
foreach($tmp1 as $i=>
$tmp){
// do each of the page numbering systems
// firstly, find the total pages for this one
$totalPages =
$totalPages1;
foreach ($this->ezPages as $pageNum=>
$id){
if (isset
($tmp[$pageNum])){
// then this must be starting page numbers
$info['dnum']=
$info['num']-
$pageNum;
// also check for the special case of the numbering stopping and starting on the same page
if (isset
($info['stopn']) || isset
($info['stoptn']) ){
} else if ($tmp[$pageNum]==
'stop' ||
$tmp[$pageNum]==
'stopt'){
// then we are stopping page numbers
} else if ($status==
1 &&
($tmp[$pageNum]==
'stoptn' ||
$tmp[$pageNum]==
'stopn')){
// then we are stopping page numbers
// then add the page numbering to this page
$num=
$pageNum+
$info['dnum'];
$total =
$totalPages+
$num-
$pageNum;
$this->reopenObject($id);
$this->addText($info['x'],$info['y'],$info['size'],$pat);
$w=
$this->getTextWidth($info['size'],$pat);
$this->addText($info['x']-
$w,$info['y'],$info['size'],$pat);
// ------------------------------------------------------------------------------
// ------------------------------------------------------------------------------
// ------------------------------------------------------------------------------
return $this->output($options);
// ------------------------------------------------------------------------------
// used to change the vertical position of the writing point.
if ( $this->y <
$this->ez['bottomMargin']){
// ------------------------------------------------------------------------------
// used to change the vertical position of the writing point.
// changes up by a positive increment, so enter a negative number to go
// if $mod is set to 'makeSpace' and a new page is forced, then the pointed will be moved
// down on the new page, this will allow space to be reserved for graphics etc.
if ( $this->y <
$this->ez['bottomMargin']){
// ------------------------------------------------------------------------------
function ezPrvtTableDrawLines($pos,$gap,$x0,$x1,$y0,$y1,$y2,$col,$inner,$outer,$opt=
1){
$this->setStrokeColor($col[0],$col[1],$col[2]);
if ($cnt==
1 ||
$cnt==
$n){
$this->setLineStyle($outer);
$this->setLineStyle($inner);
$this->line($x-
$gap/
2,$y0,$x-
$gap/
2,$y2);
$this->setLineStyle($outer);
$this->line($x0-
$gap/
2-
$outer/
2,$y0,$x1-
$gap/
2+
$outer/
2,$y0);
// only do the second line if it is different to the first, AND each row does not have
$this->line($x0-
$gap/
2,$y1,$x1-
$gap/
2,$y1);
$this->line($x0-
$gap/
2-
$outer/
2,$y2,$x1-
$gap/
2+
$outer/
2,$y2);
// ------------------------------------------------------------------------------
// uses ezText to add the text, and returns the height taken by the largest heading
// this page will move the headings to a new page if they will not fit completely on this one
// transaction support will be used to implement this
if (isset
($optionsAll['cols'])){
$options =
$optionsAll['cols'];
// $y is the position at which the top of the table should start, so the base
// of the first text, is $y-$height-$gap-$decender, but ezText starts by dropping $height
// the return from this function is the total cell height, including gaps, and $y is adjusted
// to be the postion of the bottom line
$this->transaction('start');
foreach($cols as $colName=>
$colHeading){
if (isset
($options[$colName]) && isset
($options[$colName]['justification'])){
$justification =
$options[$colName]['justification'];
$this->ezText($colHeading,$size,array('aleft'=>
$pos[$colName],'aright'=>
($maxWidth[$colName]+
$pos[$colName]),'justification'=>
$justification));
$y =
$y -
$mx -
$gap +
$decender;
// $y -= $mx-$gap+$decender;
// now, if this has moved to a new page, then abort the transaction, move to a new page, and put it there
// do not check on the second time around, to avoid an infinite loop
$this->transaction('rewind');
$y =
$this->y -
$gap-
$decender;
$this->transaction('commit');
return $mx+
$gap*
2-
$decender;
// ------------------------------------------------------------------------------
// will calculate the maximum width, taking into account that the text may be broken
foreach ($lines as $line){
$w =
$this->getTextWidth($size,$line);
// ------------------------------------------------------------------------------
function ezTable(&$data,$cols=
'',$title=
'',$options=
''){
// add a table of information to the pdf document
// $data is a two dimensional array
// $cols (optional) is an associative array, the keys are the names of the columns from $data
// to be presented (and in that order), the values are the titles to be given to the columns
// $title (optional) is the title to be put on the top of the table
// $options is an associative array which can contain:
// 'showLines'=> 0,1,2, default is 1 (show outside and top lines only), 2=> lines on each row
// 'showHeadings' => 0 or 1
// 'shaded'=> 0,1,2,3 default is 1 (1->alternate lines are shaded, 0->no shading, 2-> both shaded, second uses shadeCol2)
// 'shadeCol' => (r,g,b) array, defining the colour of the shading, default is (0.8,0.8,0.8)
// 'shadeCol2' => (r,g,b) array, defining the colour of the shading of the other blocks, default is (0.7,0.7,0.7)
// 'textCol' => (r,g,b) array, text colour
// 'rowGap' => 2 , the space added at the top and bottom of each row, between the text and the lines
// 'colGap' => 5 , the space on the left and right sides of each cell
// 'lineCol' => (r,g,b) array, defining the colour of the lines, default, black.
// 'xPos' => 'left','right','center','centre',or coordinate, reference coordinate in the x-direction
// 'xOrientation' => 'left','right','center','centre', position of the table w.r.t 'xPos'
// 'width'=> <number> which will specify the width of the table, if it turns out to not be this
// wide, then it will stretch the table to fit, if it is wider then each cell will be made
// proportionalty smaller, and the content may have to wrap.
// 'maxWidth'=> <number> similar to 'width', but will only make table smaller than it wants to be
// 'options' => array(<colname>=>array('justification'=>'left','width'=>100,'link'=>linkDataName),<colname>=>....)
// allow the setting of other paramaters for the individual columns
// 'minRowSpace'=> the minimum space between the bottom of each row and the bottom margin, in which a new row will be started
// if it is less, then a new page would be started, default=-100
// 'innerLineThickness'=>1
// 'outerLineThickness'=>1
// 'splitRows'=>0, 0 or 1, whether or not to allow the rows to be split across page boundaries
// 'protectRows'=>number, the number of rows to hold with the heading on page, ie, if there less than this number of
// rows on the page, then move the whole lot onto the next page, default=1
// note that the user will have had to make a font selection already or this will not
// produce a valid pdf file.
// take the columns from the first row of the data set
'shaded'=>
1,'showLines'=>
1,'shadeCol'=>
array(0.8,0.8,0.8),'shadeCol2'=>
array(0.7,0.7,0.7),'fontSize'=>
10,'titleFontSize'=>
12
,'titleGap'=>
5,'lineCol'=>
array(0,0,0),'gap'=>
5,'xPos'=>
'centre','xOrientation'=>
'centre'
,'showHeadings'=>
1,'textCol'=>
array(0,0,0),'width'=>
0,'maxWidth'=>
0,'cols'=>
array(),'minRowSpace'=>-
100,'rowGap'=>
2,'colGap'=>
5
,'innerLineThickness'=>
1,'outerLineThickness'=>
1,'splitRows'=>
0,'protectRows'=>
1
foreach($defaults as $key=>
$value){
if (!isset
($options[$key]) ||
!is_array($options[$key])){
if (!isset
($options[$key])){
$options['gap']=
2*
$options['colGap'];
$middle =
($this->ez['pageWidth']-
$this->ez['rightMargin'])/
2+
($this->ez['leftMargin'])/
2;
// figure out the maximum widths of the text within each column
foreach($cols as $colName=>
$colHeading){
// find the maximum cell widths based on the data
foreach($cols as $colName=>
$colHeading){
if ($w >
$maxWidth[$colName]){
// and the maximum widths to fit in the headings
foreach($cols as $colName=>
$colTitle){
if ($w >
$maxWidth[$colName]){
// calculate the start positions of each of the columns
foreach($maxWidth as $colName =>
$w){
// if the column width has been specified then set that here, also total the
// width avaliable for adjustment
if (isset
($options['cols'][$colName]) && isset
($options['cols'][$colName]['width']) &&
$options['cols'][$colName]['width']>
0){
$t=
$t+
$options['cols'][$colName]['width'];
$maxWidth[$colName] =
$options['cols'][$colName]['width']-
$options['gap'];
$setWidth +=
$options['cols'][$colName]['width'];
$t=
$t+
$w+
$options['gap'];
$setWidth +=
$options['gap'];
// if maxWidth is specified, and the table is too wide, and the width has not been set,
if ($options['width']==
0 &&
$options['maxWidth'] &&
($t-
$x)>
$options['maxWidth']){
// then need to make this one smaller
$options['width']=
$options['maxWidth'];
if ($options['width'] &&
$adjustmentWidth>
0 &&
$setWidth<
$options['width']){
// first find the current widths of the columns involved in this mystery
foreach($pos as $colName=>
$p){
if (!isset
($options['cols'][$last]) ||
!isset
($options['cols'][$last]['width']) ||
$options['cols'][$last]['width']<=
0){
$cols0[$last]=
$p-
$xq -
$options['gap'];
$presentWidth +=
($p-
$xq -
$options['gap']);
// $cols0 contains the widths of all the columns which are not set
$neededWidth =
$options['width']-
$setWidth;
// if needed width is negative then add it equally to each column, else get more tricky
if ($presentWidth<
$neededWidth){
foreach($cols0 as $colName=>
$w){
$cols0[$colName]+=
($neededWidth-
$presentWidth)/
count($cols0);
while ($presentWidth>
$neededWidth &&
$cnt<
100){
$cnt++
; // insurance policy
// find the widest columns, and the next to widest width
foreach($cols0 as $colName=>
$w){
$aWidest=
array($colName);
// then figure out what the width of the widest columns would have to be to take up all the slack
$newWidestWidth =
$widest -
($presentWidth-
$neededWidth)/
count($aWidest);
if ($newWidestWidth >
$nWidest){
// then there is space to set them to this
foreach($aWidest as $colName){
$cols0[$colName] =
$newWidestWidth;
$presentWidth=
$neededWidth;
// there is not space, reduce the size of the widest ones down to the next size down, and we
foreach($aWidest as $colName){
$cols0[$colName] =
$nWidest;
$presentWidth=
$presentWidth-
($widest-
$nWidest)*
count($aWidest);
// $cols0 now contains the new widths of the constrained columns.
// now need to update the $pos and $maxWidth arrays
foreach($pos as $colName=>
$p){
if (!isset
($options['cols'][$colName]) ||
!isset
($options['cols'][$colName]['width']) ||
$options['cols'][$colName]['width']<=
0){
if (isset
($cols0[$colName])){
$xq +=
$cols0[$colName] +
$options['gap'];
$maxWidth[$colName]=
$cols0[$colName];
if (isset
($cols1[$colName])){
// now adjust the table to the correct location across the page
switch ($options['xPos']){
$xref =
$this->ez['leftMargin'];
$xref =
$this->ez['pageWidth'] -
$this->ez['rightMargin'];
$xref =
$options['xPos'];
switch ($options['xOrientation']){
$baseLeftMargin =
$this->ez['leftMargin'];
// ok, just about ready to make me a table
$this->setColor($options['textCol'][0],$options['textCol'][1],$options['textCol'][2]);
$this->setStrokeColor($options['shadeCol'][0],$options['shadeCol'][1],$options['shadeCol'][2]);
// start a transaction which will be used to regress the table, if there are not enough rows protected
if ($options['protectRows']>
0){
$this->transaction('start');
$dm =
$this->ez['leftMargin']-
$baseLeftMargin;
foreach($basePos as $k=>
$v){
// if the title is set, then do that
$w =
$this->getTextWidth($options['titleFontSize'],$title);
$this->y -=
$this->getFontHeight($options['titleFontSize']);
if ($this->y <
$this->ez['bottomMargin']){
// margins may have changed on the newpage
$dm =
$this->ez['leftMargin']-
$baseLeftMargin;
foreach($basePos as $k=>
$v){
$this->y -=
$this->getFontHeight($options['titleFontSize']);
$this->addText($middle-
$w/
2,$this->y,$options['titleFontSize'],$title);
$this->y -=
$options['titleGap'];
// margins may have changed on the newpage
$dm =
$this->ez['leftMargin']-
$baseLeftMargin;
foreach($basePos as $k=>
$v){
$y=
$this->y; // to simplify the code a bit
$height =
$this->getFontHeight($options['fontSize']);
$decender =
$this->getFontDecender($options['fontSize']);
if ($options['showHeadings']){
// this function will move the start of the table to a new page if it does not fit on this one
$headingHeight =
$this->ezPrvtTableColumnHeadings($cols,$pos,$maxWidth,$height,$decender,$options['rowGap'],$options['fontSize'],$y,$options);
$dm =
$this->ez['leftMargin']-
$baseLeftMargin;
foreach($basePos as $k=>
$v){
// open an object here so that the text can be put in over the shading
$textObjectId =
$this->openObject();
$this->addObject($textObjectId);
$this->reopenObject($textObjectId);
// the transaction support will be used to prevent rows being split
if ($options['splitRows']==
0){
if (isset
($this->ez['columns']) &&
$this->ez['columns']['on']==
1){
$columnStart =
$this->ez['columns']['colNum'];
$this->transaction('start');
while(!$abortTable &&
$ok ==
0){
while(!$abortTable &&
($newPage ||
$newRow)){
if ($newPage ||
$y<
$this->ez['bottomMargin'] ||
(isset
($options['minRowSpace']) &&
$y<
($this->ez['bottomMargin']+
$options['minRowSpace'])) ){
// check that enough rows are with the heading
if ($options['protectRows']>
0 &&
$movedOnce==
0 &&
$cnt<=
$options['protectRows']){
// then we need to move the whole table onto the next page
$y2=
$y-
$mx+
2*
$height+
$decender-
$newRow*
$height;
if ($options['showLines']){
if (!$options['showHeadings']){
$this->ezPrvtTableDrawLines($pos,$options['gap'],$x0,$x1,$y0,$y1,$y2,$options['lineCol'],$options['innerLineThickness'],$options['outerLineThickness'],$options['showLines']);
// and the margins may have changed, this is due to the possibility of the columns being turned on
// as the columns are managed by manipulating the margins
$dm =
$this->ez['leftMargin']-
$baseLeftMargin;
foreach($basePos as $k=>
$v){
$textObjectId =
$this->openObject();
$this->addObject($textObjectId);
$this->reopenObject($textObjectId);
$this->setColor($options['textCol'][0],$options['textCol'][1],$options['textCol'][2],1);
$y =
$this->ez['pageHeight']-
$this->ez['topMargin'];
if ($options['showHeadings']){
$this->ezPrvtTableColumnHeadings($cols,$pos,$maxWidth,$height,$decender,$options['rowGap'],$options['fontSize'],$y,$options);
// if these cells need to be split over a page, then $newPage will be set, and the remaining
// text will be placed in $leftOvers
foreach($cols as $colName=>
$colTitle){
if (isset
($row[$colName])){
if (isset
($options['cols'][$colName]) && isset
($options['cols'][$colName]['link']) &&
strlen($options['cols'][$colName]['link'])){
$lines =
explode("\n",$row[$colName]);
if (isset
($row[$options['cols'][$colName]['link']]) &&
strlen($row[$options['cols'][$colName]['link']])){
foreach($lines as $k=>
$v){
$lines[$k]=
'<c:alink:'.
$row[$options['cols'][$colName]['link']].
'>'.
$v.
'</c:alink>';
$lines =
explode("\n",$row[$colName]);
$this->y -=
$options['rowGap'];
foreach ($lines as $line){
while (strlen($line) ||
$start){
$this->y=
$this->y-
$height;
if ($this->y <
$this->ez['bottomMargin']){
$newPage=
1; // whether a new page is required for any of the columns
$colNewPage=
1; // whether a new page is required for this column
if (isset
($leftOvers[$colName])){
$leftOvers[$colName].=
"\n".
$line;
$leftOvers[$colName] =
$line;
if (isset
($options['cols'][$colName]) && isset
($options['cols'][$colName]['justification']) ){
$just =
$options['cols'][$colName]['justification'];
$line=
$this->addTextWrap($pos[$colName],$this->y,$maxWidth[$colName],$options['fontSize'],$line,$just);
$dy=
$y+
$height-
$this->y+
$options['rowGap'];
if ($dy-
$height*
$newPage>
$mx){
$mx=
$dy-
$height*
$newPage;
// set $row to $leftOvers so that they will be processed onto the new page
// now add the shading underneath
if ($options['shaded'] &&
$cnt%
2==
0){
$this->setColor($options['shadeCol'][0],$options['shadeCol'][1],$options['shadeCol'][2],1);
$this->filledRectangle($x0-
$options['gap']/
2,$y+
$decender+
$height-
$mx,$x1-
$x0,$mx);
$this->reopenObject($textObjectId);
if ($options['shaded']==
2 &&
$cnt%
2==
1){
$this->setColor($options['shadeCol2'][0],$options['shadeCol2'][1],$options['shadeCol2'][2],1);
$this->filledRectangle($x0-
$options['gap']/
2,$y+
$decender+
$height-
$mx,$x1-
$x0,$mx);
$this->reopenObject($textObjectId);
if ($options['showLines']>
1){
// then draw a line on the top of each block
$this->setStrokeColor($options['lineCol'][0],$options['lineCol'][1],$options['lineCol'][2],1);
// $this->line($x0-$options['gap']/2,$y+$decender+$height-$mx,$x1-$x0,$mx);
$this->setLineStyle($options['outerLineThickness']);
$this->setLineStyle($options['innerLineThickness']);
$this->line($x0-
$options['gap']/
2,$y+
$decender+
$height,$x1-
$options['gap']/
2,$y+
$decender+
$height);
// $this->reopenObject($textObjectId);
// checking row split over pages
if ($options['splitRows']==
0){
if ( ( ($this->ezPageCount !=
$pageStart) ||
(isset
($this->ez['columns']) &&
$this->ez['columns']['on']==
1 &&
$columnStart !=
$this->ez['columns']['colNum'] )) &&
$secondTurn==
0){
// then we need to go back and try that again !
$this->transaction('rewind');
$dm =
$this->ez['leftMargin']-
$baseLeftMargin;
foreach($basePos as $k=>
$v){
$this->transaction('commit');
$ok=
1; // don't go round the loop if splitting rows is allowed
} // end of while to check for row splitting
$this->transaction('abort');
// only the outer transaction should be operational
$this->transaction('rewind');
} // end of foreach ($data as $row)
} // end of while ($abortTable)
// table has been put on the page, the rows guarded as required, commit.
$this->transaction('commit');
if ($options['showLines']){
if (!$options['showHeadings']){
$this->ezPrvtTableDrawLines($pos,$options['gap'],$x0,$x1,$y0,$y1,$y2,$options['lineCol'],$options['innerLineThickness'],$options['outerLineThickness'],$options['showLines']);
// close the object for drawing the text on top
// ------------------------------------------------------------------------------
// this function will intially be used to implement underlining support, but could be used for a range of other
$search =
array('<u>','<U>','</u>','</U>');
$replace =
array('<c:uline>','<c:uline>','</c:uline>','</c:uline>');
// ------------------------------------------------------------------------------
function ezText($text,$size=
0,$options=
array(),$test=
0){
// this will add a string of text to the document, starting at the current drawing
// it will wrap to keep within the margins, including optional offsets from the left
// and the right, if $size is not specified, then it will be the last one used, or
// the default value (12 I think).
// the text will go to the start of the next line when a return code "\n" is found.
// 'left'=> number, gap to leave from the left margin
// 'right'=> number, gap to leave from the right margin
// 'aleft'=> number, absolute left position (overrides 'left')
// 'aright'=> number, absolute right position (overrides 'right')
// 'justification' => 'left','right','center','centre','full'
// only set one of the next two items (leading overrides spacing)
// 'leading' => number, defines the total height taken by the line, independent of the font height.
// 'spacing' => a real number, though usually set to one of 1, 1.5, 2 (line spacing as used in word processing)
// if $test is set then this should just check if the text is going to flow onto a new page or not, returning true or false
// apply the filtering which will make the underlining function.
if (is_array($options) && isset
($options['aleft'])){
$left =
$this->ez['leftMargin'] +
((is_array($options) && isset
($options['left']))?
$options['left']:
0);
if (is_array($options) && isset
($options['aright'])){
$right=
$options['aright'];
$right =
$this->ez['pageWidth'] -
$this->ez['rightMargin'] -
((is_array($options) && isset
($options['right']))?
$options['right']:
0);
$size =
$this->ez['fontSize'];
$this->ez['fontSize']=
$size;
if (is_array($options) && isset
($options['justification'])){
$just =
$options['justification'];
// modifications to give leading and spacing based on those given by Craig Heydenburg 1/1/02
if (is_array($options) && isset
($options['leading'])) { ## use leading instead of spacing
$height =
$options['leading'];
} else if (is_array($options) && isset
($options['spacing'])) {
$height =
$this->getFontHeight($size) *
$options['spacing'];
$height =
$this->getFontHeight($size);
foreach ($lines as $line){
while (strlen($line) ||
$start){
$this->y=
$this->y-
$height;
if ($this->y <
$this->ez['bottomMargin']){
// and then re-calc the left and right, in case they have changed due to columns
if (is_array($options) && isset
($options['aleft'])){
$left =
$this->ez['leftMargin'] +
((is_array($options) && isset
($options['left']))?
$options['left']:
0);
if (is_array($options) && isset
($options['aright'])){
$right=
$options['aright'];
$right =
$this->ez['pageWidth'] -
$this->ez['rightMargin'] -
((is_array($options) && isset
($options['right']))?
$options['right']:
0);
$line=
$this->addTextWrap($left,$this->y,$right-
$left,$size,$line,$just,0,$test);
// ------------------------------------------------------------------------------
function ezImage($image,$pad =
5,$width =
0,$resize =
'full',$just =
'center',$border =
''){
if (stristr($image,'://'))//copy to temp file
$fp =
@fopen($image,"rb");
$image =
tempnam ("/tmp", "php-pdf");
$fp2 =
@fopen($image,"w");
if (!(file_exists($image))) return false; //return immediately if image file does not exist
return false; //return if file is not jpg or png
if ($width ==
0) $width =
$imageInfo[0]; //set width
$ratio =
$imageInfo[0]/
$imageInfo[1];
//get maximum width of image
if (isset
($this->ez['columns']) &&
$this->ez['columns']['on'] ==
1)
$bigwidth =
$this->ez['columns']['width'] -
($pad *
2);
$bigwidth =
$this->ez['pageWidth'] -
($pad *
2);
//fix width if larger than maximum or if $resize=full
if ($resize ==
'full' ||
$resize ==
'width' ||
$width >
$bigwidth)
$height =
($width/
$ratio); //set height
//fix size if runs off page
if ($height >
($this->y -
$this->ez['bottomMargin'] -
($pad *
2)))
$height =
($this->y -
$this->ez['bottomMargin'] -
($pad *
2)); //shrink height
$width =
($height*
$ratio); //fix width
//fix x-offset if image smaller than bigwidth
//center if justification=center
$offset =
($bigwidth -
$width) /
2;
//move to right if justification=right
$offset =
($bigwidth -
$width);
//leave at left if justification=left
//call appropriate function
$this->addJpegFromFile($image,$this->ez['leftMargin'] +
$pad +
$offset, $this->y +
$this->getFontHeight($this->ez['fontSize']) -
$pad -
$height,$width);
$this->addPngFromFile($image,$this->ez['leftMargin'] +
$pad +
$offset, $this->y +
$this->getFontHeight($this->ez['fontSize']) -
$pad -
$height,$width);
if (!(isset
($border['color'])))
$border['color']['red'] =
.5;
$border['color']['blue'] =
.5;
$border['color']['green'] =
.5;
if (!(isset
($border['width']))) $border['width'] =
1;
if (!(isset
($border['cap']))) $border['cap'] =
'round';
if (!(isset
($border['join']))) $border['join'] =
'round';
$this->setStrokeColor($border['color']['red'],$border['color']['green'],$border['color']['blue']);
$this->setLineStyle($border['width'],$border['cap'],$border['join']);
$this->rectangle($this->ez['leftMargin'] +
$pad +
$offset, $this->y +
$this->getFontHeight($this->ez['fontSize']) -
$pad -
$height,$width,$height);
$this->y =
$this->y -
$pad -
$height;
//remove tempfile for remote images
if ($temp ==
true) unlink($image);
// ------------------------------------------------------------------------------
// note that templating code is still considered developmental - have not really figured
// out a good way of doing this yet.
// this function will load the requested template ($file includes full or relative pathname)
// the code for the template will be modified to make it name safe, and then stored in
// an array for later use
// The id of the template will be returned for the user to operate on it later
if (substr($code,0,5)==
'<?php'){
if (isset
($this->ez['numTemplates'])){
$newNum =
$this->ez['numTemplates'];
$this->ez['numTemplates']++
;
$this->ez['numTemplates']=
1;
$this->ez['templates']=
array();
$this->ez['templates'][$newNum]['code']=
$code;
// ------------------------------------------------------------------------------
// execute the given template on the current document.
if (!isset
($this->ez['templates'][$id])){
eval
($this->ez['templates'][$id]['code']);
// ------------------------------------------------------------------------------
function alink($info,$internal=
0){
// a callback function to support the formation of clickable links within the document
$lineFactor=
0.05; // the thickness of the line as a proportion of the height. also the drop of the line.
// the beginning of the link
// this should contain the URl for the link as the 'p' entry, and will also contain the value of 'nCallback'
if (!isset
($this->ez['links'])){
$this->ez['links']=
array();
$this->ez['links'][$i] =
array('x'=>
$info['x'],'y'=>
$info['y'],'angle'=>
$info['angle'],'decender'=>
$info['decender'],'height'=>
$info['height'],'url'=>
$info['p']);
$this->setStrokeColor(0,0,1);
$thick =
$info['height']*
$lineFactor;
$this->setLineStyle($thick);
// assume that it is the most recent opening which has closed
$start =
$this->ez['links'][$i];
$this->addInternalLink($start['url'],$start['x'],$start['y']+
$start['decender'],$info['x'],$start['y']+
$start['decender']+
$start['height']);
$a =
deg2rad((float)
$start['angle']-
90.0);
$drop =
$start['height']*
$lineFactor*
1.5;
$this->line($start['x']-
$dropx,$start['y']-
$dropy,$info['x']-
$dropx,$info['y']-
$dropy);
$this->addLink($start['url'],$start['x'],$start['y']+
$start['decender'],$info['x'],$start['y']+
$start['decender']+
$start['height']);
// ------------------------------------------------------------------------------
// a callback function to support underlining
$lineFactor=
0.05; // the thickness of the line as a proportion of the height. also the drop of the line.
// the beginning of the underline zone
if (!isset
($this->ez['links'])){
$this->ez['links']=
array();
$this->ez['links'][$i] =
array('x'=>
$info['x'],'y'=>
$info['y'],'angle'=>
$info['angle'],'decender'=>
$info['decender'],'height'=>
$info['height']);
$thick =
$info['height']*
$lineFactor;
$this->setLineStyle($thick);
// assume that it is the most recent opening which has closed
$start =
$this->ez['links'][$i];
$a =
deg2rad((float)
$start['angle']-
90.0);
$drop =
$start['height']*
$lineFactor*
1.5;
$this->line($start['x']-
$dropx,$start['y']-
$dropy,$info['x']-
$dropx,$info['y']-
$dropy);
// ------------------------------------------------------------------------------
Documentation generated on Mon, 05 May 2008 16:17:08 +0400 by phpDocumentor 1.4.0